package cn.iocoder.yudao.module.portal.controller.admin;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.framework.common.pojo.PageResult;
import cn.iocoder.yudao.framework.common.util.object.BeanUtils;
import cn.iocoder.yudao.module.base.dal.dataobject.info.InfoDO;
import cn.iocoder.yudao.module.gov.controller.admin.resourcecatalog.vo.ResourceCatalogRespVO;
import cn.iocoder.yudao.module.gov.controller.admin.resourcedirectory.vo.ResourceDirectoryPageReqVO;
import cn.iocoder.yudao.module.gov.controller.admin.resourcedirectory.vo.ResourceDirectoryRespVO;
import cn.iocoder.yudao.module.gov.dal.dataobject.resourcecatalog.ResourceCatalogDO;
import cn.iocoder.yudao.module.gov.dal.dataobject.resourcedirectory.ResourceDirectoryDO;
import cn.iocoder.yudao.module.gov.service.resourcecatalog.ResourceCatalogService;
import cn.iocoder.yudao.module.gov.service.resourcedirectory.ResourceDirectoryService;
import cn.iocoder.yudao.module.portal.controller.admin.vo.*;
import cn.iocoder.yudao.module.portal.service.PortalWebService;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.tags.Tag;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.*;
import org.springframework.util.LinkedMultiValueMap;
import org.springframework.util.MultiValueMap;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;
import org.springframework.web.client.ResourceAccessException;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.annotation.security.PermitAll;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import java.net.ConnectException;
import java.util.*;
import java.util.stream.Collectors;

import static cn.iocoder.yudao.framework.common.pojo.CommonResult.success;
import static cn.iocoder.yudao.framework.security.core.util.SecurityFrameworkUtils.getPortalLoginUserId;

@Tag(name = "门户网站请求")
@RestController
@RequestMapping("/portal")
@Validated
public class portalWebController {

    @Autowired
    private ResourceCatalogService resourceCatalogService;
    @Autowired
    private ResourceDirectoryService resourceDirectoryService;
    @Autowired
    private PortalWebService portalWebService;
    private RestTemplate restTemplate = new RestTemplate();

    // 新增：JSON 解析器（处理请求参数和响应）
    private final ObjectMapper objectMapper = new ObjectMapper();
    /**
     * 查询目录树接口
     */
    @GetMapping("/get-catalogTree")
    @Operation(summary = "查询目录树接口")
    @PermitAll
    public CommonResult<List<ResourceCatalogRespVO>> getSimpleDeptList() {
        List<ResourceCatalogDO> list = resourceCatalogService.getResourceCatalogList();
        return success(BeanUtils.toBean(list, ResourceCatalogRespVO.class));
    }

    /**
     * 查询目录列表接口
     */
    @GetMapping("/ResourceDirectoryPage")
    @Operation(summary = "获得政务资源目录分页")
    @PermitAll
    public CommonResult<PageResult<ResourceDirectoryRespVO>> getResourceDirectoryPage(@Valid ResourceDirectoryPageReqVO pageReqVO) {
        Long portalLoginUserId = getPortalLoginUserId();
        if (portalLoginUserId != null){
            pageReqVO.setUserId(String.valueOf(portalLoginUserId));
        }
        pageReqVO.setStatus("0");
        PageResult<ResourceDirectoryDO> pageResult = resourceDirectoryService.getResourceDirectoryPage(pageReqVO);
        return success(BeanUtils.toBean(pageResult, ResourceDirectoryRespVO.class));
    }
    /**
     * 查询目录列表接口（推荐）
     */
    @GetMapping("/ResourceDirectoryTop")
    @Operation(summary = "获得政务资源目录分页")
    @PermitAll
    public CommonResult<List<ResourceDirectoryRespVO>> getResourceDirectoryTop(@Valid ResourceDirectoryPageReqVO pageReqVO) {
        pageReqVO.setStatus("0");
        List<ResourceDirectoryDO> pageResult = resourceDirectoryService.getResourceDirectoryTop(pageReqVO);

        // 随机抽取两条数据
        List<ResourceDirectoryDO> randomTwo = new ArrayList<>();
        if (pageResult != null && !pageResult.isEmpty()) {
            int size = pageResult.size();
            if (size <= 2) {
                // 如果数据不足两条，直接返回全部
                randomTwo.addAll(pageResult);
            } else {
                // 生成不重复的随机索引
                Random random = new Random();
                Set<Integer> indices = new HashSet<>();
                while (indices.size() < 2) {
                    int index = random.nextInt(size);
                    indices.add(index);
                }
                // 根据随机索引获取数据
                for (int index : indices) {
                    randomTwo.add(pageResult.get(index));
                }
            }
        }

        return success(BeanUtils.toBean(randomTwo, ResourceDirectoryRespVO.class));
    }
    /**
     * 目录访问量统计
     */
    @GetMapping("/addPageView")
    @Operation(summary = "访问量统计")
    @PermitAll
    public void addPageView(@RequestParam("catalogId") Long catalogId) {
        resourceDirectoryService.addPageView(catalogId);
    }
    /**
     * 根据目录id查询目录详情
     */
    @GetMapping("/getResourceDirectoryById")
    @Operation(summary = "根据目录id查询目录详情")
    @PermitAll
    public CommonResult<ResourceDirectoryVO> getResourceDirectoryById(@RequestParam("id") Long id) {
        return success(portalWebService.getResourceDirectoryById(id));
    }

    @GetMapping("/getCatalogInfo")
    @Operation(summary = "获取目录数据项分页")
    @PermitAll
    public CommonResult<CatalogInfoDataVO> getCatalogInfo(@Valid CatalogInfoPageReqVO reqVO) {
        // 直接返回核心的CatalogInfoDataVO（您需要的返回体）
        return success(portalWebService.getCatalogInfoPage(reqVO));
    }

    @Operation(summary = "查询接口列表数据列表")
    @GetMapping("/getInterfaceList")
    @PermitAll
    public CommonResult<PageResult<ResourceDirectoryRespVO>> getInterfaceList(@Valid ResourceDirectoryPageReqVO pageReqVO) {
        Long portalLoginUserId = getPortalLoginUserId();
        if (portalLoginUserId != null){
            pageReqVO.setUserId(String.valueOf(portalLoginUserId));
        }
        pageReqVO.setStatus("0");
        PageResult<ResourceDirectoryDO> pageResult = resourceDirectoryService.getInterfacePageList(pageReqVO);
        return success(BeanUtils.toBean(pageResult, ResourceDirectoryRespVO.class));
    }
    @Operation(summary = "查询接口列表数据列表(推荐)")
    @GetMapping("/getInterfaceTop")
    @PermitAll
    public CommonResult<List<ResourceDirectoryRespVO>> getInterfaceTop(@Valid ResourceDirectoryPageReqVO pageReqVO) {
        pageReqVO.setStatus("0");
        List<ResourceDirectoryDO> pageResult = resourceDirectoryService.getInterfacePageTop(pageReqVO);
        List<ResourceDirectoryDO> randomTwo = new ArrayList<>();
        if (pageResult != null && !pageResult.isEmpty()) {
            int size = pageResult.size();
            if (size <= 2) {
                // 如果数据不足两条，直接返回全部
                randomTwo.addAll(pageResult);
            } else {
                // 生成不重复的随机索引
                Random random = new Random();
                Set<Integer> indices = new HashSet<>();
                while (indices.size() < 2) {
                    int index = random.nextInt(size);
                    indices.add(index);
                }
                // 根据随机索引获取数据
                for (int index : indices) {
                    randomTwo.add(pageResult.get(index));
                }
            }
        }
        return success(BeanUtils.toBean(randomTwo, ResourceDirectoryRespVO.class));
    }
    @Operation(summary = "根据目录id查询接口基本信息")
    @GetMapping("/getInterfaceByCatalogId")
    public CommonResult<InfoDO> getInterfaceByCatalogId(@RequestParam("catalogId") Long catalogId) {
        return success(portalWebService.getInterfaceByCatalogId(catalogId));
    }
    /**
     * 收藏目录
     */
    @GetMapping("/collect")
    @Operation(summary = "收藏目录")
    public CommonResult<Boolean> collect(@RequestParam("catalogId") Long catalogId) {
        resourceDirectoryService.collect(catalogId);
        return success(true);
    }
    /**
     * 根据目录id获取数据集详情
     */
    @GetMapping("/getDataSetById")
    @Operation(summary = "根据目录id获取数据集详情")
    @PermitAll
    public CommonResult<List<CataLogDataSetVO> > getDataSetById(@RequestParam("catalogId") Long catalogId) {
        return success(portalWebService.getDataSetById(catalogId));
    }
    /**
     * 7天数据量查询接口
     * 对应URL：/portal/getDataNumBy7Day
     * 请求方式：GET
     */
    @GetMapping("/getDataNumBy7Day")
    @Operation(summary = "7天数据量查询接口")
    @PermitAll // 与现有接口一致，允许匿名访问（如需鉴权可删除此注解）
    public CommonResult<List<DataNum7DayItemVO>> getDataNumBy7Day() {
        return success(portalWebService.getDataNumBy7Day());
    }

    /**
     * 统计接口，数据集，数据项数量
     */
    @Operation(summary = "统计接口，数据集，数据项数量")
    @PermitAll
    @GetMapping("/count")
    public CommonResult<Map<String, Integer>> count() {
        return success(portalWebService.count());
    }
    @GetMapping("/downloadDataSet")
    @Operation(summary = "根据数据集id下载数据集")
    public void downloadDataSet(CataLogDataSetVO cataLogDataSetVO, HttpServletResponse response) {
        try {
            portalWebService.downloadDataSet(cataLogDataSetVO);
        } catch (Exception e) {
            // 异常处理：设置错误响应
            response.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
            try {
                response.getWriter().write("下载失败：" + e.getMessage());
            } catch (Exception ex) {
                ex.printStackTrace();
            }
        }
    }

    // ====================== 修复后的在线调试核心接口 ======================
    /**
     * 在线调试接口：接收前端传入的接口配置，后端转发请求并返回 JSON 结果
     * 支持参数：服务地址、接口路径、接口类型、请求方法、Content-Type、请求参数等
     */
    @PostMapping("/debug/online")
    @Operation(summary = "在线调试接口")
    public CommonResult<Map<String, Object>> onlineDebug(@Valid @RequestBody PortalDebugOnlineReqVO debugReq) {
        Map<String, Object> result = new HashMap<>();
        long startTime = System.currentTimeMillis();

        try {
            // 1. 拼接完整请求URL
            String fullUrl = debugReq.getServerUrl().trim() + debugReq.getApiPath().trim();
            fullUrl = fullUrl.replaceAll("//+", "/")
                    .replace("http:/", "http://")
                    .replace("https:/", "https://");

            // 2. 构建请求头
            HttpHeaders headers = new HttpHeaders();
            headers.setContentType(MediaType.parseMediaType(debugReq.getContentType()));
            if (debugReq.getCustomHeaders() != null && !debugReq.getCustomHeaders().isEmpty()) {
                debugReq.getCustomHeaders().forEach(headers::set);
            }

            // 3. 处理请求参数
            HttpEntity<?> requestEntity;
            if ("GET".equalsIgnoreCase(debugReq.getMethod())) {
                String queryStr = buildGetQueryString(debugReq.getRequestParams());
                if (!queryStr.isEmpty()) {
                    fullUrl += (fullUrl.contains("?") ? "&" : "?") + queryStr;
                }
                requestEntity = new HttpEntity<>(headers);
            } else {
                Object requestBody = parseRequestBody(debugReq.getRequestParams(), debugReq.getContentType());
                requestEntity = new HttpEntity<>(requestBody, headers);
            }

            // 4. 转发请求
            HttpMethod httpMethod = HttpMethod.valueOf(debugReq.getMethod().toUpperCase());
            ResponseEntity<String> responseEntity = restTemplate.exchange(
                    fullUrl,
                    httpMethod,
                    requestEntity,
                    String.class
            );

            // 5. 解析响应结果
            JsonNode responseJson = null;
            if (responseEntity.getBody() != null && !responseEntity.getBody().isEmpty()) {
                try {
                    responseJson = objectMapper.readTree(responseEntity.getBody());
                } catch (Exception e) {
                    result.put("responseBody", responseEntity.getBody());
                }
            }

            // 6. 封装成功结果
            Map<String, Object> requestConfig = new HashMap<>();
            requestConfig.put("serverUrl", debugReq.getServerUrl());
            requestConfig.put("apiPath", debugReq.getApiPath());
            requestConfig.put("apiType", debugReq.getApiType());
            requestConfig.put("method", debugReq.getMethod());
            requestConfig.put("contentType", debugReq.getContentType());
            requestConfig.put("fullUrl", fullUrl);
            requestConfig.put("requestParams", debugReq.getRequestParams());

            Map<String, Object> responseInfo = new HashMap<>();
            responseInfo.put("statusCode", responseEntity.getStatusCodeValue());
            Map<String, String> responseHeaders = new HashMap<>();
            responseEntity.getHeaders().forEach((k, v) -> responseHeaders.put(k, v.get(0)));
            responseInfo.put("responseHeaders", responseHeaders);
            responseInfo.put("responseBody", responseJson != null ? responseJson : "无响应内容");

            result.put("debugStatus", "SUCCESS");
            result.put("requestConfig", requestConfig);
            result.put("responseInfo", responseInfo);
            result.put("costTime", System.currentTimeMillis() - startTime + "ms");

        } catch (ResourceAccessException e) {
            // 专门处理连接超时/网络异常（关键优化）
            if (e.getCause() instanceof ConnectException) {
                result.put("errorMsg", "连接目标服务失败：网络不可达或服务未启动，请检查地址和端口");
            } else {
                result.put("errorMsg", "请求超时：目标服务未在规定时间内响应");
            }
            result.put("debugStatus", "FAIL");
            result.put("costTime", System.currentTimeMillis() - startTime + "ms");
        } catch (Exception e) {
            // 其他异常处理
            result.put("debugStatus", "FAIL");
            result.put("errorMsg", "调试失败：" + e.getMessage());
            result.put("costTime", System.currentTimeMillis() - startTime + "ms");
        }

        return success(result);
    }

    /**
     * 构建GET请求的Query字符串
     */
    private String buildGetQueryString(Map<String, Object> params) {
        if (params == null || params.isEmpty()) return "";
        StringBuilder query = new StringBuilder();
        for (Map.Entry<String, Object> entry : params.entrySet()) {
            String key = entry.getKey();
            Object value = entry.getValue();
            if (value == null) continue;

            String valueStr;
            if (value instanceof Collection) {
                valueStr = ((Collection<?>) value).stream()
                        .map(Object::toString)
                        .collect(Collectors.joining(","));
            } else {
                valueStr = value.toString();
            }

            if (query.length() > 0) {
                query.append("&");
            }
            query.append(key).append("=").append(valueStr);
        }
        return query.toString();
    }

    /**
     * 解析请求体（根据Content-Type处理）
     */
    private Object parseRequestBody(Map<String, Object> params, String contentType) throws JsonProcessingException {
        if (params == null || params.isEmpty()) return null;
        if (contentType.contains("application/json")) {
            return objectMapper.writeValueAsString(params);
        }
        if (contentType.contains("application/x-www-form-urlencoded")) {
            MultiValueMap<String, Object> formData = new LinkedMultiValueMap<>();
            for (Map.Entry<String, Object> entry : params.entrySet()) {
                Object value = entry.getValue();
                if (value instanceof Collection) {
                    formData.addAll(entry.getKey(), (List<?>) value);
                } else {
                    formData.add(entry.getKey(), value);
                }
            }
            return formData;
        }
        return objectMapper.writeValueAsString(params);
    }

}
